package master.ghrm.domain;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public abstract class AbstractBaseEntity implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * if transients should be considered in equals
	 */
	private static final boolean TEST_TRANSIENTS = false;

	/**
	 * This method returns an array of attribute names that will not be used in reflection based {@link #hashCode()},
	 * {@link #equals(Object)} and {@link #toString()} methods.
	 * 
	 * @return attribute names to exclude from reflective operation.
	 */
	protected abstract String[] getExcludedAttributes();

	/**
	 * Redefined toString() method of an Object, to consider excluded attributes
	 * 
	 * @return String MULTI LINE STYLE object
	 */
	@Override
	public String toString() {
		String returnValue = "";
		final String[] excluded = getExcludedAttributes();
		if (excluded == null || excluded.length == 0) {
			// empty excluded attributes array
			returnValue = ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
		}
		returnValue = ReflectionToStringBuilder.toStringExclude(this, excluded);

		return returnValue;
	}

	/**
	 * Redefined hashCode() method of an Object, to consider eventual existence of excluded attributes.
	 * 
	 * @return hash code
	 */
	@Override
	public int hashCode() {
		final String[] excluded = getExcludedAttributes();
		if (excluded == null || excluded.length == 0) {
			// empty excluded attributes array
			return HashCodeBuilder.reflectionHashCode(this, false);
		}
		return HashCodeBuilder.reflectionHashCode(this, excluded);
	}

	/**
	 * redefined equals() method of an Object, to consider eventual excluded attributes
	 * 
	 * @return boolean equals
	 */
	@Override
	public boolean equals(Object obj) {
		final String[] excluded = getExcludedAttributes();
		if (excluded == null || excluded.length == 0) {
			// empty excluded attributes array
			return EqualsBuilder.reflectionEquals(this, obj, TEST_TRANSIENTS);
		}
		return EqualsBuilder.reflectionEquals(this, obj, excluded);
	}

}
